package pocisk;

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import javax.swing.filechooser.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import javax.imageio.ImageIO;

public class Main {

    public static void main(String[] args) {
        Window wnd = new Window();
        wnd.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        wnd.setVisible(true);
        wnd.setMinimumSize(new Dimension(809, 635));
        wnd.setMaximumSize(wnd.getMinimumSize());
        wnd.setBounds(20, 20, 809, 635);
        wnd.setTitle("Optymalizacja toru lotu pocisku");
    }
}

class Window extends JFrame {

    public Window() {
        Container contents = getContentPane();
        MainPane mainpane = new MainPane();
        contents.add(mainpane);
    }
}

class MainPane extends JPanel {

    static World swiat;
    static ToolPane tpane;

    MainPane() {
        setLayout(null);
        setBackground(Color.BLACK);
        setSize(800, 600);
        tpane = new ToolPane();
        tpane.setBounds(600, 0, 200, 600);
        tpane.setBorder(BorderFactory.createRaisedBevelBorder());
        add(tpane);
        swiat = new World();
        swiat.setSize(new Dimension(600, 600));
        swiat.setBorder(BorderFactory.createRaisedBevelBorder());
        add(swiat);
        initializeTestingCase();    // inicjalizaca początkowych planet
    }

    // inicjalizuj początkowe wartości do testowania, żeby nie wczytywać plików za każdym razem
    void initializeTestingCase() {
        MainPane.tpane.others.planets.add(new Planet(2, 300, 500, 16000));
        MainPane.tpane.others.planets.add(new Planet(3, 450, 250, 36000));
        MainPane.tpane.others.planets.add(new Planet(1, 100, 100, 1000));

    }

    public static void simulate() {

        swiat.initsimulation();

        //POTRZEBNE ZMIENNE
        /*
        WEJŚCIE:
        MainPane.tpane.params.grawitacji - stala grawitacji [double]
        MainPane.tpane.params.poczatkowa - predkosc poczatkowa [double]
        MainPane.swiat.sx - Xowa startu pocisku [int]
        MainPane.swiat.sy - Ykowa startu pocisku [int]
        MainPane.swiat.cx - Xowa celu [int]
        MainPane.swiat.cy - Ykowa celu [int]

        WYJŚCIE - tutaj wpisywać wyniki:
        MainPane.tpane.results.angle - zmienna decyzyjna kąt wystrzału - naprzykład 'w górę' 0 stopni, w prawo 90, w dół 180, w lewo 270 [int]
        MainPane.tpane.results.masaplanety0 - zmienna decyzyjna masa najbliższej planety [double]
         */
    }

    public static void repaintall() {
        swiat.repaint();
        tpane.repaint();
        tpane.params.repaint();
        tpane.methods.repaint();
        tpane.results.repaint();
        tpane.others.repaint();
    }

    public static void loadParam(String[] ext) {
        JFileChooser fileopen = new JFileChooser();
        for (int i = 0; i < ext.length; i++) {
            fileopen.addChoosableFileFilter(new FileNameExtensionFilter("Pliki " + ext[i], ext[i]));
        }
        int ret = fileopen.showDialog(null, "Otwórz plik");
        if (ret == JFileChooser.APPROVE_OPTION) {
            tpane.params.pfile = fileopen.getSelectedFile();
        }
    }

    public static void loadWorld(String[] ext) {
        JFileChooser fileopen = new JFileChooser();
        for (int i = 0; i < ext.length; i++) {
            fileopen.addChoosableFileFilter(new FileNameExtensionFilter("Pliki " + ext[i], ext[i]));
        }
        int ret = fileopen.showDialog(null, "Otwórz plik");
        if (ret == JFileChooser.APPROVE_OPTION) {
            tpane.world = fileopen.getSelectedFile();
        }
        initWorld(tpane.world);
    }

    public static void initWorld(File world) {
        try {
            String s = "";
            FileReader fr = new FileReader(world);
            BufferedReader br = new BufferedReader(fr);
            MainPane.tpane.others.planets = new ArrayList<Planet>();
            while ((s = br.readLine()) != null) {

                String[] arr = s.split(" ");
                MainPane.tpane.others.planets.add(new Planet(Integer.parseInt(arr[0]), Integer.parseInt(arr[1]), Integer.parseInt(arr[2]), Double.parseDouble(arr[3])));
            }
        } catch (Exception e) {
            alert("Exception", "Błąd przy wczytywaniu planet");
            e.printStackTrace();
        }
    }

    public static void saveFile(String inp, String[] ext) {
        JFileChooser fileopen = new JFileChooser();
        for (int i = 0; i < ext.length; i++) {
            fileopen.addChoosableFileFilter(new FileNameExtensionFilter("Pliki " + ext[i], ext[i]));
        }
        int ret = fileopen.showDialog(null, "Zapisz plik");
        if (ret == JFileChooser.APPROVE_OPTION) {
            File target = fileopen.getSelectedFile();
            try {
                FileWriter fw = new FileWriter(target);
                fw.write(inp);
                fw.close();
            } catch (IOException e) {
                MainPane.alert("IOException", "Brak dostępu do pliku");
            }
        }
    }

    public static void alert(String ex, String msg) {
        JOptionPane.showMessageDialog(null, msg, "Wystąpił wyjątek " + ex, JOptionPane.ERROR_MESSAGE);
    }

    public static boolean inRange(double a, double b, int r) {
        if (a > b - r && a < b + r) {
            return true;
        }
        return false;
    }
}

class ToolPane extends JPanel implements ActionListener {

    static File world;
    static JButton b1, b2;
    static Params params;
    static Metody methods;
    static Wyniki results;
    static Inne others;

    ToolPane() {
        super();
        setLayout(null);
        setBackground(Color.GRAY);
        setSize(200, 600);
        b1 = new JButton("LOAD WORLD");
        b1.setBounds(10, 5, 180, 30);
        add(b1);
        b1.addActionListener(this);
        b2 = new JButton("SAVE WORLD");
        b2.setBounds(10, 35, 180, 30);
        add(b2);
        b2.addActionListener(this);
        params = new Params();
        params.setBounds(10, 70, 180, 170);
        params.setBorder(BorderFactory.createTitledBorder(BorderFactory.createRaisedBevelBorder(), "Parametry"));
        add(params);
        methods = new Metody();
        methods.setBounds(10, 245, 180, 90);
        methods.setBorder(BorderFactory.createTitledBorder(BorderFactory.createRaisedBevelBorder(), "Metody numeryczne"));
        add(methods);
        results = new Wyniki();
        results.setBounds(10, 450, 180, 73);
        results.setBorder(BorderFactory.createTitledBorder(BorderFactory.createRaisedBevelBorder(), "Wyniki"));
        add(results);
        others = new Inne();
        others.setBounds(10, 340, 180, 105);
        others.setBorder(BorderFactory.createTitledBorder(BorderFactory.createRaisedBevelBorder(), "Inne"));
        add(others);

    }

    public void actionPerformed(ActionEvent event) {
        String[] arr = {"map"};
        if (event.getSource() == b2) {
            String inp = "";
            for (Planet p : MainPane.tpane.others.planets) {
                inp += p.icon + " " + p.x + " " + p.y + " " + p.mass + "\r\n";
            }
            MainPane.saveFile(inp, arr);
        } else {
            MainPane.loadWorld(arr);
            MainPane.repaintall();
        }
    }
}

class Metody extends JPanel implements ActionListener {

    int metoda;
    JRadioButton m1, m2, m3;
    ButtonGroup bg;

    Metody() {
        super();
        setLayout(null);
        setBackground(new Color(160, 160, 160));
        metoda = 1;
        m1 = new JRadioButton("Metoda Hooka-Jeevesa");
        m1.setActionCommand("1");
        m1.setSelected(true);
        m2 = new JRadioButton("Metoda Nelder-Meada");
        m2.setActionCommand("2");
        m2.setSelected(true);
        m3 = new JRadioButton("Metoda Rosenbrocka");
        m3.setActionCommand("3");
        m3.setSelected(true);
        bg = new ButtonGroup();
        bg.add(m1);
        bg.add(m2);
        bg.add(m3);
        m1.addActionListener(this);
        m2.addActionListener(this);
        m3.addActionListener(this);

        add(m1);
        add(m2);
        add(m3);

        m1.setBounds(10, 20, 160, 20);
        m1.setBackground(new Color(160, 160, 160));
        m2.setBounds(10, 40, 160, 20);
        m2.setBackground(new Color(160, 160, 160));
        m3.setBounds(10, 60, 160, 20);
        m3.setBackground(new Color(160, 160, 160));
    }

    public void actionPerformed(ActionEvent e) {
        metoda = Integer.parseInt(e.getActionCommand());
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setFont(new Font("sansserif", Font.BOLD, 12));
    }
}

class Wyniki extends JPanel {

    double angle, masaplanety0, precyzja;

    Wyniki() {
        super();
        setLayout(null);
        setBackground(new Color(160, 160, 160));
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setFont(new Font("sansserif", Font.BOLD, 12));
        g2d.drawString("Kąt strzału:  " + ((double) ((int) (angle * 100))) / 100d, 15, 30);
        g2d.drawString("Masa planety 0:  " + ((double) ((int) (masaplanety0 * 100))) / 100d, 15, 46);
        g2d.drawString("Odległość od celu:  " + ((double) ((int) (precyzja * 100))) / 100d, 15, 62);
    }
}

class Params extends JPanel implements DocumentListener, ActionListener {

    static JButton b1, b2;
    static JTextField v0, g, delta;
    double poczatkowa, grawitacji, dt;
    static File pfile;

    Params() {

        super();
        poczatkowa = 40;
        grawitacji = 80;
        dt = 0.1;

        setLayout(null);
        setBackground(new Color(160, 160, 160));
        b1 = new JButton("LOAD PARAM");
        b2 = new JButton("SAVE PARAM");
        b1.setBounds(30, 20, 120, 30);
        b2.setBounds(30, 50, 120, 30);
        add(b1);
        add(b2);
        b1.addActionListener(this);
        b2.addActionListener(this);
        v0 = new JTextField();
        g = new JTextField();
        delta = new JTextField();
        v0.setBounds(55, 87, 80, 20);
        g.setBounds(55, 112, 80, 20);
        delta.setBounds(55, 137, 80, 20);
        add(v0);
        add(g);
        add(delta);
        v0.setVisible(true);
        g.setVisible(true);
        delta.setVisible(true);
        initFields();

        v0.getDocument().addDocumentListener(this);
        g.getDocument().addDocumentListener(this);
        delta.getDocument().addDocumentListener(this);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setFont(new Font("sansserif", Font.BOLD, 12));
        g2d.drawString("V0:", 23, 102);
        g2d.drawString("G:", 23, 127);
        g2d.drawString("Dt:", 23, 152);

    }

    public void initFields() {
        v0.setText("" + poczatkowa);
        g.setText("" + grawitacji);
        delta.setText("" + dt);
    }

    public void loadParam() {
        String s = "";
        try {
            FileReader fr = new FileReader(pfile);
            BufferedReader br = new BufferedReader(fr);

            String[] arr;
            s = br.readLine();
            arr = s.split(" ");
            poczatkowa = Double.parseDouble(arr[1]);
            grawitacji = Double.parseDouble(arr[2]);
            dt = Double.parseDouble(arr[3]);
            s = br.readLine();
            arr = s.split(" ");
            MainPane.swiat.sx = Integer.parseInt(arr[0]);
            MainPane.swiat.sy = Integer.parseInt(arr[1]);
            s = br.readLine();
            arr = s.split(" ");
            MainPane.swiat.cx = Integer.parseInt(arr[0]);
            MainPane.swiat.cy = Integer.parseInt(arr[1]);
            fr.close();
            initFields();
        } catch (Exception e) {
            MainPane.alert("IOException", "Błędny format pliku parametrów");
        }
    }

    public void actionPerformed(ActionEvent event) {
        Object source = event.getSource();
        String[] arr = {"param"};
        if (source == b1) {
            MainPane.loadParam(arr);
            loadParam();
            MainPane.repaintall();
        } else {
            //zero dodane na poczatku dla kompatybilnosci ze wczesniejszymi save'ami gdzie parametrem była masa pocisku też
            MainPane.saveFile(0 + " " + poczatkowa + " " + grawitacji + " " + dt + "\r\n" + MainPane.swiat.sx + " " + MainPane.swiat.sy + "\r\n" + MainPane.swiat.cx + " " + MainPane.swiat.cy + "\r\n", arr);
        }
    }

    public void changedUpdate(DocumentEvent e) {
        textChanged(e);
    }

    public void removeUpdate(DocumentEvent e) {
        textChanged(e);
    }

    public void insertUpdate(DocumentEvent e) {
        textChanged(e);
    }

    public void textChanged(DocumentEvent e) {
        Document source = e.getDocument();
        String temp = "";
        try {
            if (source == v0.getDocument()) {
                poczatkowa = Double.parseDouble(temp = source.getText(0, source.getLength()));
            } else if (source == g.getDocument()) {
                grawitacji = Double.parseDouble(temp = source.getText(0, source.getLength()));
            } else {
                dt = Double.parseDouble(temp = source.getText(0, source.getLength()));
            }
        } catch (BadLocationException ex) {
        } catch (NumberFormatException ex) {
            if (!temp.equals("")) {
                MainPane.alert("NumberFormatException", "Niepoprawna wprowadzona liczba: " + temp);
            }
        } catch (ArrayIndexOutOfBoundsException ex) {
        }
        MainPane.repaintall();
    }
}

class Inne extends JPanel implements DocumentListener, ActionListener {

    static JTextField masa;
    double newplanetmass;
    JButton b1;
    ArrayList<Planet> planets;

    Inne() {
        super();
        setLayout(null);
        setBackground(new Color(160, 160, 160));
        masa = new JTextField();
        planets = new ArrayList<Planet>();
        masa.setBounds(55, 75, 80, 20);
        add(masa);
        masa.setVisible(true);
        masa.setText("" + newplanetmass);
        masa.getDocument().addDocumentListener(this);
        b1 = new JButton("SIMULATE");
        b1.setBounds(75, 15, 95, 40);
        add(b1);
        b1.addActionListener(this);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setFont(new Font("sansserif", Font.BOLD, 12));
        g2d.drawString("Masa nowej planety:", 30, 70);
        g2d.drawString(" - Cel", 30, 30);
        g2d.drawString(" - Start", 30, 50);
        g2d.setColor(Color.blue);
        g2d.fillOval(15, 22, 8, 8);
        g2d.setColor(Color.green);
        g2d.fillRect(15, 42, 8, 8);
    }

    public void changedUpdate(DocumentEvent e) {
        textChanged(e);
    }

    public void removeUpdate(DocumentEvent e) {
        textChanged(e);
    }

    public void insertUpdate(DocumentEvent e) {
        textChanged(e);
    }

    public void textChanged(DocumentEvent e) {
        Document source = e.getDocument();
        String temp = "";

        try {
            newplanetmass = Double.parseDouble(temp = source.getText(0, source.getLength()));
        } catch (BadLocationException ex) {
        } catch (NumberFormatException ex) {
            if (!temp.equals("")) {
                MainPane.alert("NumberFormatException", "Niepoprawna wprowadzona liczba: " + temp);
            }
        } catch (ArrayIndexOutOfBoundsException ex) {
        }

        MainPane.repaintall();
    }

    public void actionPerformed(ActionEvent e) {
        MainPane.simulate();
    }
}

class World extends JPanel implements MouseListener, MouseMotionListener {

    static int skala;
    boolean isStart, isTarget, isNew;
    public int cx = 150, cy = 150, sx = 450, sy = 450;
    int lastmouseX, lastmouseY;
    Planet currentplanet;
    Image e1, e2, e3;
    public ArrayList<Point2D.Double> points;      //lista położeń
    boolean iconsFound;

    World() {
        super();
        setLayout(null);
        setBackground(Color.LIGHT_GRAY);
        iconsFound = false;
        try {
            try {
                e1 = ImageIO.read(new File("build\\classes\\pocisk\\e1.gif"));
                e2 = ImageIO.read(new File("build\\classes\\pocisk\\e2.gif"));
                e3 = ImageIO.read(new File("build\\classes\\pocisk\\e3.gif"));

                iconsFound = true;
            } catch (javax.imageio.IIOException ex) {
                iconsFound = false;
                MainPane.alert("IIOException", "Blad ladowania obrazkow planet ");
            }
        } catch (IOException ex) {
            iconsFound = false;
            MainPane.alert("IOException", "Blad ladowania obrazkow planet ");
        }
        addMouseMotionListener(this);
        addMouseListener(this);
        isStart = false;
        isTarget = false;
        isNew = false;
        points = new ArrayList();
    }

    public void initsimulation() {
        HitTargetFunction fun = new HitTargetFunction(this);

        if (MainPane.tpane.methods.metoda == 1) {
            Hooke hook = new Hooke();
            double[] start = {90d, 300d}; //punkt startowy dla metody
            double epsilon = 1; //ograniczenie - dokładność
            int maxiter = 100; //ograniczenie - maksymalna ilość iteracji algorytmu
            hook.compute(start, epsilon, fun, maxiter);
            MainPane.tpane.results.angle = (int) hook.result()[0];
            MainPane.tpane.results.masaplanety0 = hook.result()[1];
        } else if (MainPane.tpane.methods.metoda == 2) {
            NelderMead nelder = new NelderMead();
            ArrayList<Double[]> simplex = new ArrayList<Double[]>();
            simplex.add(new Double[]{90d, 100d});
            simplex.add(new Double[]{40d, 10d});
            simplex.add(new Double[]{10d, 900d}); //tablica punktów startowych
            double[] res = nelder.nelderMead(simplex, fun, 0.1, 200);
            MainPane.tpane.results.angle = res[0];
            MainPane.tpane.results.masaplanety0 = res[1];
        } else {
            //na razie sztywna symulacja
            MainPane.tpane.results.angle = -7340;
            MainPane.tpane.results.masaplanety0 = 1500;
            simulate(MainPane.tpane.results.angle, MainPane.tpane.results.masaplanety0);
        }

        double[] wynikowe = {MainPane.tpane.results.angle, MainPane.tpane.results.masaplanety0};
        MainPane.tpane.results.precyzja = fun.function(wynikowe);

        if (MainPane.tpane.results.angle < 0) {
            double oldangle = Math.abs(MainPane.tpane.results.angle);
            for (int i = 0; i < oldangle / 360d; i++) {
                MainPane.tpane.results.angle += 360;
            }
        }
        MainPane.repaintall();
    }

    public void simulate(double angle, double mass0) {

        double oldmass = 0;
        boolean emptyworld = MainPane.tpane.others.planets.isEmpty();
        Planet nearest = null;
        if (!emptyworld) {
            nearest = MainPane.tpane.others.planets.get(0);
            MyPoint2D nearestpoint = new MyPoint2D(nearest.x, nearest.y);
            MyPoint2D startpoint = new MyPoint2D(sx, sy);
            for (Planet p : MainPane.tpane.others.planets) {
                MyPoint2D planetpoint = new MyPoint2D(p.x, p.y);
                if (planetpoint.distance(startpoint) < nearestpoint.distance(startpoint)) {
                    nearest = p;
                    nearestpoint = new MyPoint2D(nearest.x, nearest.y);
                }
            }
            oldmass = nearest.mass;
            nearest.mass = mass0;
        }

        Simulation simulation = new Simulation(
                MainPane.tpane.methods.metoda,
                MainPane.tpane.params.grawitacji,
                MainPane.tpane.params.poczatkowa,
                MainPane.tpane.others.planets,
                MainPane.swiat.sx,
                MainPane.swiat.sy,
                MainPane.swiat.cx,
                MainPane.swiat.cy,
                angle, //MainPane.tpane.results.angle, // kat wystrzału
                MainPane.tpane.params.dt // dt
                );
        points = new ArrayList();       // przy każej symulacji nowy zestaw punktów
        Point2D.Double[] initialTemp = simulation.initialStep();    // pierwszy krok symulacji, pierwsze wyliczone położenie
        Point2D.Double pp = initialTemp[0];     // poprzedni punkt
        Point2D.Double cp = initialTemp[1];     // aktualny punkt
        int iteration = 1;                      // licznik iteracji pętli

        //pętla ma na celu dodanie punktu gdzie aktualnie znajduje się obiekt do tablicy i wyrysowanie całego panelu od nowa
        do {
            points.add(cp);                     // dodaj punkt do tablicy
            Point2D.Double[] temp = simulation.nextStep(new Point2D.Double[]{pp, cp});  // następny krok symulacji
            pp = new Point2D.Double(temp[0].x, temp[0].y);  // nadpisywanie punktu poprzedniego
            cp = new Point2D.Double(temp[1].x, temp[1].y);  // nadpisywanie punktu aktualnego
            iteration++;
        } while (iteration < 2000 && cp.x < 600 && cp.x >= 0 && cp.y >= 0 && cp.y < 600);
        // warunki kontynuowania symulacji
        repaint();
        if (!emptyworld) {
            nearest.mass = oldmass;
        }
    }

    public double totalDistance() {

        double result = 0;
        for (int i = 1; i < points.size(); i++) {
            result += points.get(i - 1).distance(points.get(i));
        }
        return result;
    }

    /**
     * Rysowanie punktów i toru pocisku
     */
    public void drawPositions(Graphics g) {
        Color temp = g.getColor();
        g.setColor(Color.red);
        Point2D.Double prev = null;
        for (Point2D.Double p : points) {
            g.drawRect((int) p.x - 1, transf((int) p.y) - 1, 3, 3);
            //g.drawRect((int)p.x, transf((int)p.y), 1, 1); // rysowanie piksela
            if (prev != null) {
                g.drawLine((int) p.x, transf((int) p.y), (int) prev.x, transf((int) prev.y));
            }
            prev = p;
        }
        g.setColor(temp);
    }

    private int transf(int y) {
        return (-y + 600);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        drawPositions(g);
        //NOWE PLANETY WYRYSOWANE
        g2d.setColor(Color.red);
        if (iconsFound) {
            g2d.drawImage(e1, 8, 12, this);
            g2d.drawImage(e2, 22, 10, this);
            g2d.drawImage(e3, 15, 27, this);
        } else {
            g2d.fillOval(8 - 8, 12 - 3, 6, 6);
            g2d.fillOval(22 - 6, 10 - 6, 12, 12);
            g2d.fillOval(15 - 8, 27 - 8, 16, 16);
        }
        g2d.setColor(Color.black);
        float dash[] = {5.0f};
        g2d.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_BUTT,
                BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f));
        for (int i = 50; i < 600; i = i + 50) {
            g2d.draw(new Line2D.Double(i, 0, i, 600));
            g2d.draw(new Line2D.Double(0, i, 600, i));
        }
        g2d.setStroke(new BasicStroke(1));
        g2d.setFont(new Font("sansserif", Font.BOLD, 16));
        g2d.drawString("Wszechświat", 290, 30);
        g2d.setFont(new Font("sansserif", Font.BOLD, 12));
        g2d.drawString("Y", 8, 561);
        g2d.drawString("X", 40, 595);
        g2d.drawString("Nowe planety", 5, 60);
        g2d.drawString("Czarna dziura", 518, 60);
        g2d.fillOval(568, 18, 18, 18);
        g2d.drawString("(" + lastmouseX + "," + lastmouseY + ")", 540, 590);
        g2d.draw(new Line2D.Double(10, 565, 10, 590));
        g2d.draw(new Line2D.Double(10, 590, 35, 590));

        g2d.setColor(Color.blue);
        g2d.fillOval(cx - 4, (-cy + 600) - 4, 8, 8);
        g2d.setColor(Color.green);
        g2d.fillRect(sx - 4, (-sy + 600) - 4, 8, 8);

        g2d.setColor(Color.red);
        for (Planet p : MainPane.tpane.others.planets) {
            if (p.icon == 1) {
                if (iconsFound) {
                    g2d.drawImage(e1, p.x - 3, (-p.y + 600) - 3, this);
                } else {
                    g2d.fillOval(p.x - 8, (-p.y + 600) - 3, 6, 6);
                }
            } else if (p.icon == 2) {
                if (iconsFound) {
                    g2d.drawImage(e2, p.x - 7, (-p.y + 600) - 7, this);
                } else {
                    g2d.fillOval(p.x - 6, (-p.y + 600) - 6, 12, 12);
                }
            } else if (p.icon == 3) {
                if (iconsFound) {
                    g2d.drawImage(e3, p.x - 9, (-p.y + 600) - 9, this);
                } else {
                    g2d.fillOval(p.x - 8, (-p.y + 600) - 8, 16, 16);
                }
            }

        }
    }

    public void mousePressed(MouseEvent e) {

        double mouseX = e.getX();
        double mouseY = -(e.getY() - 600);

        if (MainPane.inRange(mouseX, MainPane.swiat.sx, 10) && MainPane.inRange(mouseY, MainPane.swiat.sy, 10)) {

            isStart = true;
        } else if (MainPane.inRange(mouseX, MainPane.swiat.cx, 10) && MainPane.inRange(mouseY, MainPane.swiat.cy, 10)) {

            isTarget = true;
        } else {
            for (Planet p : MainPane.tpane.others.planets) {
                if (MainPane.inRange(mouseX, p.x, 14) && MainPane.inRange(mouseY, p.y, 14)) {
                    currentplanet = p;
                    break;
                }
            }

            if (currentplanet == null && MainPane.inRange(mouseX, 8.0d, 10) && MainPane.inRange(mouseY, 588.0d, 10)) {
                currentplanet = new Planet(1, (int) mouseX, (int) mouseY, MainPane.tpane.others.newplanetmass);
                MainPane.tpane.others.planets.add(currentplanet);
            } else if (currentplanet == null && MainPane.inRange(mouseX, 22.0d, 15) && MainPane.inRange(mouseY, 590.0d, 15)) {
                currentplanet = new Planet(2, (int) mouseX, (int) mouseY, MainPane.tpane.others.newplanetmass);
                MainPane.tpane.others.planets.add(currentplanet);
            } else if (currentplanet == null && MainPane.inRange(mouseX, 17.0d, 18) && MainPane.inRange(mouseY, 567.0d, 18)) {
                currentplanet = new Planet(3, (int) mouseX, (int) mouseY, MainPane.tpane.others.newplanetmass);
                MainPane.tpane.others.planets.add(currentplanet);
            }

        }
    }

    public void mouseReleased(MouseEvent e) {
        isStart = false;
        isTarget = false;
        double mouseX = e.getX();
        double mouseY = -(e.getY() - 600);
        if (currentplanet != null && MainPane.inRange(mouseX, 568.0d, 18) && MainPane.inRange(mouseY, 582.0d, 18)) {
            MainPane.tpane.others.planets.remove(currentplanet);
        }
        currentplanet = null;
    }

    public void mouseDragged(MouseEvent e) {
        double mouseX = e.getX();
        double mouseY = -(e.getY() - 600);
        lastmouseX = e.getX();
        lastmouseY = -(e.getY() - 600);
        if (isStart) {
            sx = (int) mouseX;
            sy = (int) mouseY;
        } else if (isTarget) {
            cx = (int) mouseX;
            cy = (int) mouseY;

        } else if (currentplanet != null) {
            currentplanet.x = (int) mouseX;
            currentplanet.y = (int) mouseY;
        }
        MainPane.repaintall();

    }

    public void mouseMoved(MouseEvent e) {
        lastmouseX = e.getX();
        lastmouseY = -(e.getY() - 600);
        repaint();
    }

    public void mouseClicked(MouseEvent arg0) {
    }

    public void mouseEntered(MouseEvent arg0) {
    }

    public void mouseExited(MouseEvent e) {
        isStart = false;
        isTarget = false;
        currentplanet = null;
    }
}



